import threading

from mongoengine import connect
import datetime
import os
import sys
from pathlib import Path
from platform_tool.utils.yaml_utils import YamlToDictUtils
from apiview_doc.decorator import ApiDoc


# 环境dev/test/pre/prod
SERVER_ENV = 'dev' if os.environ.get(
    'PLATFORM') is None else os.environ.get('PLATFORM')
# Build paths inside the project like this: BASE_DIR / 'subdir'.
BASE_DIR = Path(__file__).resolve().parent.parent

YAML_TO_DICT = YamlToDictUtils(
    filePath = f'{BASE_DIR}/config/application.{SERVER_ENV}.yml')

sys.path.insert(0, os.path.join(BASE_DIR, 'apps'))

# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/3.2/howto/deployment/checklist/

# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = 'django-insecure-u8$i8t=55@7_h_qm9&7m9)@hm9k6_q1bn(yzem$cklc)pl54&^'

# SERVER_APPID
SERVER_APPID = YAML_TO_DICT.get('server').get('appId')

# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = YAML_TO_DICT.get('server').get('debug')
# ========================================================= #
# *******************rabbitmq配置***************** #
# ========================================================= #

RABBITMQ_USERNAME = YAML_TO_DICT.get('server').get('rabbitmq').get('username')
RABBITMQ_PWSSWORD = YAML_TO_DICT.get('server').get('rabbitmq').get('password')
RABBITMQ_HOST = YAML_TO_DICT.get('server').get('rabbitmq').get('host')
RABBITMQ_PORT = YAML_TO_DICT.get('server').get('rabbitmq').get('port')
RABBITMQ_NAME = YAML_TO_DICT.get('server').get('rabbitmq').get('name')

# ========================================================= #
# *******************django_celery_beat配置***************** #
# ========================================================= #

REDIS_URL = f"{YAML_TO_DICT.get('server').get('redis').get('host')}:" \
            f"{YAML_TO_DICT.get('server').get('redis').get('port')}"

# CELERY_BROKER_URL = f'amqp://{RABBITMQ_USERNAME}:{RABBITMQ_USERNAME}@{RABBITMQ_HOST}:{RABBITMQ_PORT}/{RABBITMQ_NAME}'

CELERY_BROKER_URL = f'redis://{REDIS_URL}/8'
BROKER_URL = CELERY_BROKER_URL

CELERY_CACHE_BACKEND = 'django-cache'  # celery 后端缓存

# django 缓存
CACHES = {
    "default": {
        "BACKEND": "django_redis.cache.RedisCache",
        "LOCATION": f"redis://{REDIS_URL}/1",
        "OPTIONS": {
            "CLIENT_CLASS": "django_redis.client.DefaultClient",
            "SERIALIZER": "django_redis.serializers.json.JSONSerializer",
        }
    }
}

CELERY_RESULT_BACKEND = f'redis://{REDIS_URL}/9'  # 结果存储地址
CELERY_ACCEPT_CONTENT = ['application/json']  # 指定任务接收的内容序列化类型
CELERY_TASK_SERIALIZER = 'json'  # 任务序列化方式
CELERY_RESULT_SERIALIZER = 'json'  # 任务结果序列化方式
CELERY_TASK_RESULT_EXPIRES = 12 * 30  # 超过时间
CELERY_MESSAGE_COMPRESSION = 'zlib'  # 是否压缩
CELERY_WORKER_CONCURRENCY = 20  # 并发数默认已CPU数量定
CELERYD_PREFETCH_MULTIPLIER = 20  # celery worker 每次去redis取任务的数量
CELERYD_MAX_TASKS_PER_CHILD = 3  # 每个worker最多执行3个任务就摧毁，避免内存泄漏
CELERYD_FORCE_EXECV = True  # 可以防止死锁
CELERY_ENABLE_UTC = True  # 关闭时区
DJANGO_CELERY_BEAT_TZ_AWARE = False
CELERY_BEAT_SCHEDULER = 'django_celery_beat.schedulers.DatabaseScheduler'  # 定时任务调度器

ALLOWED_HOSTS = ['*']

# Application definition

INSTALLED_APPS = [
    'simpleui',
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',

    'corsheaders',
    'rest_framework',
    'django_http_log',
    'apiview_doc',
    'django_comment_migrate',

    'person.apps.PersonConfig',
]

MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'corsheaders.middleware.CorsMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
    'common.middleware.logger.LogMiddleware',
    'common.middleware.trace.TraceMiddleware',
]

# -----------------------跨域设置------------------------------
CORS_ALLOW_CREDENTIALS = True
CORS_ORIGIN_ALLOW_ALL = True

CORS_ALLOW_METHODS = (
    'GET',
    'POST',
)

CORS_ALLOW_HEADERS = (
    'x-requested-with',
    'content-type',
    'accept',
    'origin',
    'authorization',
    'x-csrftoken',
    'accesstoken',
    'appid',
    'project',
    'Access-Control-Allow-Origin'
)

ROOT_URLCONF = 'platform_auth.urls'

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [os.path.join(BASE_DIR, 'templates')],

        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
            ],
        },
    },
]

WSGI_APPLICATION = 'platform_auth.wsgi.application'

# Database
# https://docs.djangoproject.com/en/3.2/ref/settings/#databases

DATABASES = {
    'default': {
        'ENGINE': YAML_TO_DICT.get('server').get('database').get('engine'),
        'NAME': YAML_TO_DICT.get('server').get('database').get('name'),
        'HOST': YAML_TO_DICT.get('server').get('database').get('host'),
        'PORT': YAML_TO_DICT.get('server').get('database').get('port'),
        'USER': YAML_TO_DICT.get('server').get('database').get('username'),
        'PASSWORD': YAML_TO_DICT.get('server').get('database').get('password')
    }
}

# Password validation
# https://docs.djangoproject.com/en/3.2/ref/settings/#auth-password-validators

AUTH_PASSWORD_VALIDATORS = [
    {
        'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
    },
]

# Internationalization
# https://docs.djangoproject.com/en/3.2/topics/i18n/

LANGUAGE_CODE = 'zh-hans'

TIME_ZONE = 'Asia/Shanghai'

USE_I18N = True

USE_L10N = True

USE_TZ = False

# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/3.2/howto/static-files/

STATIC_URL = '/static/'

# STATIC_ROOT = os.path.join(BASE_DIR, "static")

STATICFILES_DIRS = [
    os.path.join(BASE_DIR, "static"),
    os.path.join(BASE_DIR, "static/apidoc/css"),
]

# Default primary key field type
# https://docs.djangoproject.com/en/3.2/ref/settings/#default-auto-field

DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'

# eureka setting
IS_EUREKA = YAML_TO_DICT.get('server').get('isEureka')

EUREKA_SERVER = YAML_TO_DICT.get('server').get(
    'eureka').get('server').get('host')

EUREKA_CLIENT_APP_NAME = YAML_TO_DICT.get('server').get(
    'eureka').get('client').get('app_name')

EUREKA_CLIENT_PORT = YAML_TO_DICT.get('server').get(
    'eureka').get('client').get('port')

# mongo

MONGO_DB_NAME = YAML_TO_DICT.get('server').get('mongodb').get('db')
MONGO_DB_HOST = YAML_TO_DICT.get('server').get('mongodb').get('host')
MONGO_DB_PORT = YAML_TO_DICT.get('server').get('mongodb').get('port')
connect(db = MONGO_DB_NAME, host = MONGO_DB_HOST, port = MONGO_DB_PORT)

# 日志黑名单
LOG_BLACK_LIST = [
    '/log/list',
    '/log/info',
    '/base/candidateExport',
    '/base/upload',
    '/case/base/template',
    '/case/base/upload',
]

# token失效设置
EXPIRE_TIMEOUT = YAML_TO_DICT.get('server').get('jwt').get('expire')
JWT_EXPIRATION_DELTA = datetime.datetime.now(
) + datetime.timedelta(seconds = EXPIRE_TIMEOUT)

# 隐藏右侧SimpleUI广告链接和使用分析
SIMPLEUI_HOME_INFO = False
SIMPLEUI_ANALYSIS = False

# 接口文档
APIDOC_DECORATOR = ApiDoc()
APIVIEW_DOC_TITLE = 'PLATFORM_AUTH 接口文档'
APIVIEW_DOC_VERSION = 'v1.0.0'

#
REST_FRAMEWORK = {
    'DEFAULT_AUTHENTICATION_CLASSES': (
        'rest_framework_simplejwt.authentication.JWTAuthentication',
    )
}
